﻿using Cognitum.CassandraProviders.Cassandra;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Configuration.Provider;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Profile;
using System.Web.Security;

namespace Cognitum.ProvidersTests
{
    [TestFixture]
    internal class ProfileProviderTests : BaseProvidersTest
    {
        #region Methods

        [Test]
        public void DeleteInactiveProfiles_NothingAddedToDatabase()
        {
            int result2 = _providerProfile.GetNumberOfInactiveProfiles(ProfileAuthenticationOption.All, DateTime.Now);
            // Arrange
            // Act
            int result = _providerProfile.DeleteInactiveProfiles(ProfileAuthenticationOption.All, DateTime.Now);
            // Assert
            Assert.AreEqual(result2, result);
            int result3 = _providerProfile.GetNumberOfInactiveProfiles(ProfileAuthenticationOption.All, DateTime.Now);
            Assert.AreEqual(0, result3);
        }

        [Test]
        public void DeleteInactiveProfiles_SreActive_NotDelete()
        {
            int totalRecords2;
            int inactive = _providerProfile.GetNumberOfInactiveProfiles(ProfileAuthenticationOption.All, DateTime.Now);
            _providerProfile.GetAllProfiles(ProfileAuthenticationOption.All, 0, 100, out totalRecords2);
            // Arrange
            AddDefaultUser(_userName, _email);
            int totalRecords;
            // Act
            int result = _providerProfile.DeleteInactiveProfiles(ProfileAuthenticationOption.All, DateTime.Now.AddMinutes(-10));
            int result2 = _providerProfile.GetNumberOfInactiveProfiles(ProfileAuthenticationOption.All, DateTime.Now);
            _providerProfile.GetAllProfiles(ProfileAuthenticationOption.All, 0, 100, out totalRecords);
            // Assert
            Assert.AreEqual(inactive, result);
            Assert.AreEqual(inactive, result2);
            Assert.AreEqual(totalRecords2 + 1, totalRecords);
            //Clean
            DeleteUser(_userName);
        }

        [Test]
        public void DeleteInactiveProfiles_OneInactiveOneActive()
        {
            int totalRecords2;
            _providerProfile.GetAllProfiles(ProfileAuthenticationOption.All, 0, 100, out totalRecords2);
            // Arrange
            AddDefaultUser(_userName, _email);
            int totalRecords;
            System.Threading.Thread.Sleep(3000);
            AddDefaultUser("userdName", "email");
            // Act
            int result = _providerProfile.DeleteInactiveProfiles(ProfileAuthenticationOption.All, DateTime.Now);
            System.Threading.Thread.Sleep(3000);
            int result2 = _providerProfile.GetNumberOfInactiveProfiles(ProfileAuthenticationOption.All, DateTime.Now);
            _providerProfile.GetAllProfiles(ProfileAuthenticationOption.All, 0, 100, out totalRecords);
            // Assert
            Assert.AreEqual(1, result);
            Assert.AreEqual(1, result2);
            Assert.AreEqual(totalRecords2 + 1 > 100 ? 100 : totalRecords2 + 1, totalRecords);
            DeleteUser(_userName);
            DeleteUser("userdName");
        }

        [Test]
        public void DeleteProfiles()
        {
            // Arrange
            AddDefaultUser(_userName, _email);
            AddDefaultUser("userdName", "am@a.pl");
            string[] profiles = new string[2];
            profiles[0] = _userName;
            profiles[1] = "userdName";
            int totalRecords;
            // Act
            int result = _providerProfile.DeleteProfiles(profiles);
            ProfileInfoCollection profileCollection = _providerProfile.FindProfilesByUserName(
                ProfileAuthenticationOption.All, _userName, 0, 10, out totalRecords);
            // Assert
            Assert.AreEqual(2, result);
            Assert.AreEqual(0, totalRecords);
            Assert.AreEqual(0, profileCollection.Count);
            //Clean
            DeleteUser(_userName);
            DeleteUser("userdName");
        }

        [Test]
        public void DeleteProfiles_EmptyDatabase()
        {
            // Arrange
            string[] profiles = new string[2];
            profiles[0] = _userName;
            profiles[1] = "userdName";
            // Act
            // Assert
            Assert.Throws(
                typeof(ProviderException),
                delegate { _providerProfile.DeleteProfiles(profiles); });
        }

        [Test]
        public void DeleteProfiles_EmptyList()
        {
            // Arrange
            AddDefaultUser(_userName, _email);
            AddDefaultUser("userdName", "am@a.pl");
            string[] profiles = new string[2];
            // Act
            // Assert
            Assert.Throws(
               typeof(ProviderException),
               delegate { _providerProfile.DeleteProfiles(profiles); });
            //Clean
            DeleteUser(_userName);
            DeleteUser("userdName");
        }

        [Test]
        public void DeleteProfiles_NullList()
        {
            // Arrange
            AddDefaultUser(_userName, _email);
            AddDefaultUser("userdName", "am@a.pl");
            string[] profiles = null;
            // Act
            // Assert
            Assert.Throws(
               typeof(NullReferenceException),
               delegate { _providerProfile.DeleteProfiles(profiles); });
            //Clean
            DeleteUser(_userName);
            DeleteUser("userdName");
        }

        [Test]
        public void DeleteProfilesByUsernames()
        {
            // Arrange
            AddDefaultUser(_userName, _email);
            AddDefaultUser("userdName", "am@a.pl");
            ProfileInfoCollection profiles = new ProfileInfoCollection();
            profiles.Add(new ProfileInfo(_userName, false, DateTime.Now, DateTime.Now.AddMinutes(-10), 3));
            profiles.Add(new ProfileInfo("userdName", false, DateTime.Now, DateTime.Now.AddMinutes(-10), 3));
            // Act
            int result = _providerProfile.DeleteProfiles(profiles);
            // Assert
            Assert.AreEqual(2, result);
            //Clean
            DeleteUser(_userName);
            DeleteUser("userdName");
        }

        [Test]
        public void DeleteProfilesByUsernames_EmptyDatabase()
        {
            // Arrange
            ProfileInfoCollection profiles = new ProfileInfoCollection();
            profiles.Add(new ProfileInfo(_userName, false, DateTime.Now, DateTime.Now.AddMinutes(-10), 3));
            profiles.Add(new ProfileInfo("userdName", false, DateTime.Now, DateTime.Now.AddMinutes(-10), 3));
            // Act
            // Assert
            Assert.Throws(
              typeof(ProviderException),
              delegate { _providerProfile.DeleteProfiles(profiles); });
        }

        [Test]
        public void DeleteProfilesByUsernames_NullParameter()
        {
            // Arrange
            ProfileInfoCollection profiles = null;
            // Act
            // Assert
            Assert.Throws(
              typeof(NullReferenceException),
              delegate { _providerProfile.DeleteProfiles(profiles); });
        }

        [Test]
        public void FindInactiveProfilesByUserName()
        {
            // Arrange
            AddDefaultUser(_userName, _email);
            AddDefaultUser("userdName", "am@a.pl");
            AddDefaultUser("userdName2", "am2@a.pl");
            System.Threading.Thread.Sleep(3000);
            int totalRecords;
            // Act
            ProfileInfoCollection result = _providerProfile.FindInactiveProfilesByUserName(
                ProfileAuthenticationOption.All, _userName, DateTime.Now, 0, 100, out totalRecords);
            // Assert
            Assert.AreEqual(1, result.Count);
            Assert.AreEqual(1, totalRecords);
            Assert.IsNotNull(result);
            //Clean
            DeleteUser(_userName);
            DeleteUser("userdName");
            DeleteUser("userdName2");
        }

        [Test]
        public void FindInactiveProfilesByUserName_AllActive()
        {
            // Arrange
            AddDefaultUser(_userName, _email);
            AddDefaultUser("userdName", "am@a.pl");
            AddDefaultUser("userdName2", "am2@a.pl");
            int totalRecords;
            // Act
            ProfileInfoCollection result = _providerProfile.FindInactiveProfilesByUserName(
                ProfileAuthenticationOption.All, "n", DateTime.Now, 0, 100, out totalRecords);
            // Assert
            Assert.AreEqual(0, result.Count);
            Assert.AreEqual(0, totalRecords);
            Assert.IsNotNull(result);
            //Clean
            DeleteUser(_userName);
            DeleteUser("userdName");
            DeleteUser("userdName2");
        }

        [Test]
        public void FindInactiveProfilesByUserName_EmptyDatabase()
        {
            // Arrange
            int totalRecords;
            // Act
            ProfileInfoCollection result = _providerProfile.FindInactiveProfilesByUserName(
                ProfileAuthenticationOption.All, "use", DateTime.Now, 0, 100, out totalRecords);
            // Assert
            Assert.AreEqual(0, totalRecords);
            Assert.IsNotNull(result);
        }

        [Test]
        public void FindInactiveProfilesByUserName_FindByPartOfUserName()
        {
            // Arrange
            AddDefaultUser(_userName, _email);
            AddDefaultUser("userdName", "am@a.pl");
            AddDefaultUser("userdName2", "am2@a.pl");
            System.Threading.Thread.Sleep(3000);
            int totalRecords;
            // Act
            ProfileInfoCollection result = _providerProfile.FindInactiveProfilesByUserName(
                ProfileAuthenticationOption.All, "use", DateTime.Now, 0, 100, out totalRecords);
            // Assert
            Assert.AreEqual(2, totalRecords);
            Assert.AreEqual(2, result.Count);
            Assert.IsNotNull(result);
            //Clean
            DeleteUser(_userName);
            DeleteUser("userdName");
            DeleteUser("userdName2");
        }

        [Test]
        public void FindProfilesByUserName()
        {
            // Arrange
            AddDefaultUser(_userName, _email);
            AddDefaultUser("userdName", "am@a.pl");
            AddDefaultUser("userdName2", "am2@a.pl");
            int totalRecords;
            // Act
            ProfileInfoCollection result = _providerProfile.FindProfilesByUserName(
                ProfileAuthenticationOption.All, "use", 0, 100, out totalRecords);
            // Assert
            Assert.AreEqual(2, result.Count);
            Assert.AreEqual(2, totalRecords);
            Assert.IsNotNull(result);
            //Clean
            DeleteUser(_userName);
            DeleteUser("userdName");
            DeleteUser("userdName2");
        }

        [Test]
        public void FindProfilesByUserName_EmptyDatabase()
        {
            // Arrange
            int totalRecords;
            // Act
            ProfileInfoCollection result = _providerProfile.FindProfilesByUserName(
                ProfileAuthenticationOption.All, "use", 0, 100, out totalRecords);
            // Assert
            Assert.AreEqual(0, result.Count);
            Assert.IsNotNull(result);
        }

        [Test]
        public void GetAllInactiveProfiles()
        {
            // Arrange
            AddDefaultUser(_userName, _email);
            AddDefaultUser("userdName", "am@a.pl");
            System.Threading.Thread.Sleep(3000);
            AddDefaultUser("userdName2", "am2@a.pl");
            int totalRecords;
            // Act
            ProfileInfoCollection result = _providerProfile.GetAllInactiveProfiles(
                ProfileAuthenticationOption.All, DateTime.Now, 0, 100, out totalRecords);
            // Assert
            Assert.AreEqual(2, result.Count);
            Assert.AreEqual(2, totalRecords);
            Assert.IsNotNull(result);
            //Clean
            DeleteUser(_userName);
            DeleteUser("userdName");
            DeleteUser("userdName2");
        }

        [Test]
        public void GetAllProfiles()
        {
            int totalRecords2;
            _providerProfile.GetAllProfiles(ProfileAuthenticationOption.All, 0, 100, out totalRecords2);
            // Arrange
            AddDefaultUser(_userName, _email);
            AddDefaultUser("userdName", "am@a.pl");
            AddDefaultUser("userdName2", "am2@a.pl");
            int totalRecords;
            // Act
            ProfileInfoCollection result = _providerProfile.GetAllProfiles(ProfileAuthenticationOption.All, 0, 100, out totalRecords);
            // Assert
            Assert.AreEqual(totalRecords2 + 3 > 100 ? 100 : totalRecords2 + 3, result.Count);
            Assert.AreEqual(totalRecords2 + 3, totalRecords);
            Assert.IsNotNull(result);
            //Clean
            DeleteUser(_userName);
            DeleteUser("userdName");
            DeleteUser("userdName2");
        }

        [Test]
        public void GetNumberOfInactiveProfiles_AllActive()
        {
            // Arrange
            AddDefaultUser(_userName, _email);
            AddDefaultUser("userdName", "am@a.pl");
            AddDefaultUser("userdName2", "am2@a.pl");
            // Act
            int result = _providerProfile.GetNumberOfInactiveProfiles(
                ProfileAuthenticationOption.All, DateTime.Now);
            // Assert
            Assert.AreEqual(0, result);
            //Clean
            DeleteUser(_userName);
            DeleteUser("userdName");
            DeleteUser("userdName2");
        }

        [Test]
        public void GetNumberOfInactiveProfiles_OneInactive()
        {
            // Arrange
            AddDefaultUser(_userName, _email);
            AddDefaultUser("userdName", "am@a.pl");
            System.Threading.Thread.Sleep(3000);
            AddDefaultUser("userdName2", "am2@a.pl");
            // Act
            int result = _providerProfile.GetNumberOfInactiveProfiles(
                ProfileAuthenticationOption.All, DateTime.Now);
            // Assert
            Assert.AreEqual(2, result);
            //Clean
            DeleteUser(_userName);
            DeleteUser("userdName");
            DeleteUser("userdName2");
        }

        [SetUp]
        public override void Init()
        {
            base.Init();
            _providerProfile = new CassandraProfileProvider();
            _providerProfile.Initialize("CustomProfileProvider", _conf);
        }

        [Test]
        public void SetPropertyValues_GetPropertyValues()
        {
            // Arrange
            AddDefaultUser(_userName, _email);
            SettingsContext context = new SettingsContext();
            context.Add("UserName", _userName);
            SettingsPropertyCollection collection = new SettingsPropertyCollection();
            collection.Add(new SettingsProperty(Cognitum.CassandraProviders.Cassandra.CassandraProfileProvider.PropertyNames.Gender)
            {
                DefaultValue = 1,
                PropertyType = typeof(int)
            });
            SettingsPropertyValueCollection collectionSet = new SettingsPropertyValueCollection();
            collectionSet.Add(new SettingsPropertyValue(new SettingsProperty(Cognitum.CassandraProviders.Cassandra.CassandraProfileProvider.PropertyNames.Gender)
            {
                DefaultValue = 1,
                PropertyType = typeof(int)
            }));
            // Act
            _providerProfile.SetPropertyValues(context, collectionSet);
            SettingsPropertyValueCollection result = _providerProfile.GetPropertyValues(context, collection);
            // Assert
            Assert.AreEqual(1, result[Cognitum.CassandraProviders.Cassandra.CassandraProfileProvider.PropertyNames.Gender].PropertyValue);

            collectionSet = new SettingsPropertyValueCollection();
            collectionSet.Add(new SettingsPropertyValue(new SettingsProperty(Cognitum.CassandraProviders.Cassandra.CassandraProfileProvider.PropertyNames.Gender)
            {
                DefaultValue = 0,
                PropertyType = typeof(int)
            }));
            // Act
            _providerProfile.SetPropertyValues(context, collectionSet);
            result = _providerProfile.GetPropertyValues(context, collection);
            // Assert
            Assert.AreEqual(0, result[Cognitum.CassandraProviders.Cassandra.CassandraProfileProvider.PropertyNames.Gender].PropertyValue);
            //Clean
            DeleteUser(_userName);
        }

        #endregion Methods
    }
}